<template>
  <el-scrollbar
    class="mb-tree"
    v-loading="loading"
    @click="handleClearSelect">
    <el-tree
      ref="mbtreeRef"
      class="menu-custom-tree"
      style="--el-tree-node-content-height: 36px;"
      :data="apps"
      node-key="id"
      :highlight-current="true"
      :default-expanded-keys="expandedKeys"
      :props="treeSetting"
      @click.native.stop="empty"
      @node-click="handleClick">
      <template #default="{ node, data }">
        <span
          class="menu-custom-tree-node"
          style="position: relative;overflow: hidden;">
          <span
            class="menu-custom-icon"
            :class="{ 'menu-root-icon': !isFuncModule(data), 'menu-icon-module': isFuncModule(data) }"
            v-tippy="{ arrow: true }"
            content="云函数JS模块">
              <JIcon
                v-if="data.id === -100"
                :icon="DFT_ICONS.platform"
              />
              <JIcon
                v-else-if="data.id === -1"
                :icon="DFT_ICONS.global"
              />
              <JIcon
                v-else-if="data.isApp"
                :icon="DFT_ICONS.app"
              />
              <template v-else-if="isFuncModule(data)">
                  <JIcon :icon="DFT_ICONS.js"/>
              </template>
              <JIcon v-else :icon="DFT_ICONS.other"/>
          </span>
          <span
            style="text-overflow: ellipsis;overflow: hidden;padding-right: 20px;"
            v-tippy="{ arrow: true }"
            :content="getNodeTip(data)">{{ data.name }}
          </span>

          <div
            @click.stop="empty"
            v-if="hasModuleCreatePermission(data) || hasFuncModuleEdit(data)">
              <el-dropdown
                trigger="click"
                placement="bottom-start"
                size="small"
                style="position:absolute;right: 0px;"
                @command="handleTreeCommand($event, data)">
                  <JIcon
                    :icon="DFT_ICONS.more"
                    class="btn-more"
                    v-tippy="{ arrow: true }"
                    content="更多操作" />
                <template #dropdown>
                  <el-dropdown-menu>
                      <template v-if="hasModuleCreatePermission(data)">
                          <el-dropdown-item command="module"><i class="el-icon-plus"></i>函数包</el-dropdown-item>
                      </template>
                      <template v-if="hasFuncModuleEdit(data)">
                          <el-dropdown-item command="edit"><i class="el-icon-edit"></i>修改</el-dropdown-item>
                          <el-dropdown-item command="remove"><i class="el-icon-delete"></i>删除</el-dropdown-item>
                      </template>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
          </div>
        </span>
      </template>
    </el-tree>

    <el-dialog
      :title="formModuleWinName"
      v-model="formModuleWinShow"
      :close-on-click-modal="false"
      :append-to-body="true">
      <func-module
        v-if="formModuleWinShow"
        :current-data="currentData"
        @close="handleFormClose"
      />
    </el-dialog>
  </el-scrollbar>
</template>

<script setup>
import {ref, watch, onMounted} from 'vue';
import _ from 'lodash';
import {isFuncModule, hasModuleCreatePermission, hasFuncModuleEdit} from './common.js'
import FuncModule from './form-module.vue';
import {DFT_ICONS} from "@jzl/icons";
import {api} from "@jzl/api";

const props = defineProps({
  appId: Number
});

const emit = defineEmits(['select']);

const apps = ref([]);
const items = ref([]);
const app = ref(null);
const loading = ref(false);
const currentData = ref({});
const expandedKeys = ref([]);
const formModuleWinName = ref('');
const formModuleWinShow = ref(false);
const type = ref(3);
const mbtreeRef = ref(null);

const treeSetting = {
  children: 'subs',
  label: 'name',
  'icon-class': 'hello-icon'
};

const init = async () => {
  await loadRoot();
  let ids = _.map(apps.value, 'id');
  expandedKeys.value = ids;
};

const empty = () => {
};

const refreshCurrentNode = async (key) => {
  await init();

  let id = _.get(currentData.value, 'id');

  if (key) {
    id = key;
  }

  expandedKeys.value = [id];

  let data = _.getTreeData(apps.value, 'id', key, 'subs');

  if (data) {
    handleClick(data);
  }
};

const loadRoot = async () => {
  loading.value = true;

  let appsData = await loadApps();
  let itemsData = await api.func.moduleListAll();

  itemsData = _.map(itemsData, fm => {
    fm.name = _.get(fm, 'func_module_name');
    return fm;
  });

  _.each(appsData, appData => {
    let subs = [];

    // 全局
    if (appData.id === -100) {
      subs = _.filter(itemsData, {type: 1});
    } else if (appData.id === -1) {
      subs = _.filter(itemsData, {type: 2});
    } else {
      subs = _.filter(itemsData, {app_id: appData.id});
    }

    appData.subs = subs;
  });

  apps.value = appsData;
  loading.value = false;
};

const loadApps = async () => {
  let ret = await api.admin.getMyApps();
  let myApps = _.get(ret, 'apps', []);
  let appsData = [{
    nodeType: 'plat',
    name: '平台内置',
    id: -100
  }, {
    nodeType: 'system',
    name: '项目全局',
    id: -1
  }];

  let xMyApps = _.map(myApps, app => {
    return {
      nodeType: 'app',
      name: `${_.get(app, 'group_name')}`,
      id: _.get(app, 'group_id'),
      isApp: true
    }
  });

  appsData = _.concat(appsData, xMyApps);

  if (props.appId) {
    appsData = _.filter(appsData, ap => {
      return ap && (ap.id === props.appId || ap.id < 0);
    });
  }

  return appsData;
};


const handleClick = (data, node, ele) => {
  currentData.value = data;
  if (!data) return;

  if (mbtreeRef.value.store.nodesMap && mbtreeRef.value.store.nodesMap[data.id]) {
    mbtreeRef.value.store.nodesMap[data.id].expanded = true;
  }

  emit('select', data);
};

const handleClearSelect = () => {
  try {
    mbtreeRef.value.setCurrentNode({id: null});
  } catch (e) {
  }
};

const handleShowCreateModule = () => {
  if (!currentData.value || !hasModuleCreatePermission(currentData.value)) {
    return;
  }

  let name = _.get(currentData.value, 'name');

  formModuleWinName.value = `【${name}】下添加函数包`;
  formModuleWinShow.value = true;
};

const handleShowEdit = () => {
  let name = _.get(currentData.value, 'name');

  if (isFuncModule(currentData.value)) {
    formModuleWinShow.value = true;
    formModuleWinName.value = `修改函数包【${name}】`;
  }
};

const handleShowDelete = () => {
  let dt = currentData.value;
  if (!dt) return;

  let isModule = isFuncModule(dt);

  if (!isModule) return;

  let msg = `确定删除函数包【${dt.name}】?`;
  $jui.alert(msg).then(async () => {
    let ret = await api.func.moduleRemove(dt.func_module_id);
    let key = '';

    if (ret) {
      if (ret.app_id > 0) {
        key = ret.app_id;
      } else if (ret.project_id > 0) {
        key = -1;
      } else {
        key = -100;
      }
    }

    await refreshCurrentNode(key);
  }).catch(e => {
  });
};

const handleTreeCommand = (cmd, data) => {
  currentData.value = data;

  if (cmd === 'module') {
    handleShowCreateModule();
  } else if (cmd === 'edit') {
    handleShowEdit();
  } else if (cmd === 'remove') {
    handleShowDelete();
  }
}

const handleFormClose = (isUpdate) => {
  formModuleWinShow.value = false;

  if (isUpdate) {
    refreshCurrentNode();
  }
}

const getNodeTip = (data) => {
  let tip = _.get(data, "name");
  let code = _.get(data, "func_module_code");

  if (code) {
    tip += `(${data.func_module_code})`;
  }

  return tip;
}

onMounted(() => {
  init();
});

watch(() => props.appId, () => {
  init();
});

</script>

<style lang="scss" scoped>
.mb-wrap {
  background: #FFF;

  .mb-info {
    .info {
      padding-top: 10px;

      .service-form {
        flex: 1;
      }

      .service-marks {
        width: 500px;
        margin: 0 20px;
      }
    }
  }
}

.menu-custom-tree-node {
  width: 100%;
  position: relative;

  .menu-custom-icon {
    //border-radius: 3px;
    //background: #FEFEFE;
    //color: #666;
    //box-shadow: 0 0 1px #ddd;

    i {
      font-size: 14px;
    }
  }
}
</style>
